#include <QCoreApplication>
#include <QUdpSocket>
#include <QTimer>
#include <QDateTime>
#include <QDebug>
#include <QTextStream>

class UDPServer : public QObject
{
    Q_OBJECT

public:
    UDPServer(quint16 port, QObject *parent = nullptr)
        : QObject(parent)
        , m_port(port)
        , m_socket(new QUdpSocket(this))
        , m_timer(new QTimer(this))
        , m_totalBytes(0)
        , m_packetCount(0)
        , m_lastBytes(0)
        , m_lastPacketCount(0)
        , m_isReceiving(false)
        , m_noDataTimeout(0)
    {
        // 连接socket信号
        connect(m_socket, &QUdpSocket::readyRead, this, &UDPServer::readPendingDatagrams);
        
        // 设置统计定时器，每秒更新一次
        connect(m_timer, &QTimer::timeout, this, &UDPServer::updateStats);
        m_timer->setInterval(1000); // 1秒间隔
        
        m_startTime = QDateTime::currentDateTime();
        m_lastStatsTime = m_startTime;
        m_lastReceiveTime = m_startTime;
    }

    bool startServer()
    {
        if (!m_socket->bind(QHostAddress::Any, m_port)) {
            qCritical() << "无法绑定到端口" << m_port << ":" << m_socket->errorString();
            return false;
        }
        
        qInfo() << "UDP服务器启动成功，监听端口:" << m_port;
        qInfo() << "等待iperf客户端连接...";
        qInfo() << "使用命令: iperf -c <服务器IP> -p" << m_port << "-u -b 1000M -l 1288 -P 1 -t 10";
        qInfo() << "按 Ctrl+C 停止服务器";
        qInfo() << "----------------------------------------";
        
        return true;
    }

private slots:
    void readPendingDatagrams()
    {
        if (!m_isReceiving) {
            m_isReceiving = true;
            m_startTime = QDateTime::currentDateTime();
            m_lastStatsTime = m_startTime;
            m_timer->start();
            qInfo() << "开始接收数据..." << m_startTime.toString("hh:mm:ss");
        }

        while (m_socket->hasPendingDatagrams()) {
            QByteArray datagram;
            datagram.resize(m_socket->pendingDatagramSize());
            QHostAddress sender;
            quint16 senderPort;

            qint64 bytesRead = m_socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
            
            if (bytesRead > 0) {
                m_totalBytes += bytesRead;
                m_packetCount++;
                m_lastReceiveTime = QDateTime::currentDateTime(); // 更新最后接收时间
                m_noDataTimeout = 0; // 重置超时计数
                
                // 第一个数据包时显示客户端信息
                if (m_packetCount == 1) {
                    qInfo() << "客户端连接:" << sender.toString() << ":" << senderPort;
                    qInfo() << "数据包大小:" << bytesRead << "字节";
                }
            }
        }
    }

    void updateStats()
    {
        QDateTime currentTime = QDateTime::currentDateTime();
        qint64 timeDiff = m_lastStatsTime.msecsTo(currentTime);
        
        // 检查是否超时（3秒内没有接收到数据包）
        qint64 noDataTime = m_lastReceiveTime.msecsTo(currentTime);
        if (m_isReceiving && noDataTime > 3000) {
            m_noDataTimeout++;
            if (m_noDataTimeout >= 1) { // 连续1次检查都没有数据
                // 客户端断开连接
                m_timer->stop();
                m_isReceiving = false;
                
                // 显示最终统计
                qint64 totalTimeDiff = m_startTime.msecsTo(m_lastReceiveTime);
                double finalAvgRate = 0;
                if (totalTimeDiff > 0) {
                    finalAvgRate = (m_totalBytes * 8.0 * 1000.0) / (totalTimeDiff * 1024 * 1024);
                }
                
                qInfo() << "========================================";
                qInfo() << "客户端断开连接，测试结束";
                QString finalStats = QString("最终统计: 总接收: %1 bytes (%2 MB) | 数据包: %3 | 测试时长: %4 秒 | 平均速率: %5 Mbps")
                                     .arg(m_totalBytes)
                                     .arg(m_totalBytes / (1024.0 * 1024.0), 0, 'f', 2)
                                     .arg(m_packetCount)
                                     .arg(totalTimeDiff / 1000.0, 0, 'f', 2)
                                     .arg(finalAvgRate, 0, 'f', 2);
                qInfo().noquote() << finalStats;
                qInfo() << "========================================";
                qInfo() << "等待新的客户端连接...";
                
                // 重置状态，等待下一个客户端
                m_totalBytes = 0;
                m_packetCount = 0;
                m_lastBytes = 0;
                m_lastPacketCount = 0;
                m_noDataTimeout = 0;
                return;
            }
        }
        
        if (timeDiff > 0 && m_isReceiving) {
            // 计算当前速率 (最近1秒的数据)
            qint64 bytesDiff = m_totalBytes - m_lastBytes;
            double currentRate = (bytesDiff * 8.0 * 1000.0) / (timeDiff * 1024 * 1024); // Mbps
            
            // 计算当前PPS (最近1秒的数据包数)
            qint64 packetDiff = m_packetCount - m_lastPacketCount;
            double currentPPS = (packetDiff * 1000.0) / timeDiff;
            
            // 计算平均速率 (从开始到现在的总体平均)
            qint64 totalTimeDiff = m_startTime.msecsTo(currentTime);
            double avgRate = 0;
            if (totalTimeDiff > 0) {
                avgRate = (m_totalBytes * 8.0 * 1000.0) / (totalTimeDiff * 1024 * 1024); // Mbps
            }
            
            // 格式化输出：总接收: xxx bytes (xxx MB) | 数据包: xxx | 当前速率: xxx Mbps | 当前PPS: xxx | 平均速率: xxx Mbps
            QString stats = QString("总接收: %1 bytes (%2 MB) | 数据包: %3 | 当前速率: %4 Mbps | 当前PPS: %5 | 平均速率: %6 Mbps")
                           .arg(m_totalBytes)
                           .arg(m_totalBytes / (1024.0 * 1024.0), 0, 'f', 2)
                           .arg(m_packetCount)
                           .arg(currentRate, 0, 'f', 2)
                           .arg(currentPPS, 0, 'f', 2)
                           .arg(avgRate, 0, 'f', 2);
            
            qInfo().noquote() << stats;
            
            m_lastStatsTime = currentTime;
            m_lastBytes = m_totalBytes;
            m_lastPacketCount = m_packetCount;
        }
    }

private:
    quint16 m_port;
    QUdpSocket *m_socket;
    QTimer *m_timer;
    qint64 m_totalBytes;
    qint64 m_packetCount;
    QDateTime m_startTime;
    QDateTime m_lastStatsTime;
    QDateTime m_lastReceiveTime;
    qint64 m_lastBytes;
    qint64 m_lastPacketCount;
    bool m_isReceiving;
    int m_noDataTimeout;
};

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    
    // 默认端口12345，与iperf命令行参数匹配
    quint16 port = 12345;
    
    // 检查命令行参数
    QStringList args = app.arguments();
    if (args.size() > 1) {
        bool ok;
        quint16 customPort = args[1].toUShort(&ok);
        if (ok && customPort > 0) {
            port = customPort;
        } else {
            qWarning() << "无效的端口号，使用默认端口" << port;
        }
    }
    
    UDPServer server(port);
    
    if (!server.startServer()) {
        return 1;
    }
    
    return app.exec();
}

#include "main.moc"
